package com.zjbbkj.baibai.netty.message.factory;

import com.zjbbkj.baibai.common.utils.wanli.MyUtils;
import com.zjbbkj.baibai.common.utils.wanli.RedisCacheUtil;
import com.zjbbkj.baibai.netty.maps.ContainerMaps;
import com.zjbbkj.baibai.netty.message.receive.ReceiveADV;
import com.zjbbkj.baibai.netty.message.receive.ReceiveAID;
import com.zjbbkj.baibai.netty.message.receive.ReceiveRP;
import com.zjbbkj.baibai.netty.message.receive.ReceiveRS;
import com.zjbbkj.baibai.netty.message.receive.ReceivePing;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import static com.zjbbkj.baibai.netty.constants.NettySomeThing.CHARSET;
import static com.zjbbkj.baibai.netty.message.factory.calculateUsingFactory.calculateUsingFactory;

/**
 * 收到设备发过来的报文并解析报文
 * @author: Mr.WanLi
 * @create: 2021-08-01 10:44
 **/
@Slf4j
@Component
public class OperatorFactory {

    @Resource
    private RedisCacheUtil redisCacheUtil;

    static Map<String, Operation> operationMap = new HashMap<>();
    static {
        operationMap.put("PG", new ReceivePing());
        operationMap.put("DV", new ReceiveADV());
        operationMap.put("ID", new ReceiveAID());
        operationMap.put("RP", new ReceiveRP());
        operationMap.put("RS", new ReceiveRS());
    }

    /**
     * 解析报文
     *
     * @param message
     * @param channel
     * @throws Exception
     */
    public void OperatorFactory(String message, Channel channel) {
        //服务器接收到消息后进行解析
        if (MyUtils.isNull(message)) {
            return;
        }
        String[] msg = message.split("");
        if (msg[0].equals("_")) {
            //格式标识规范"_"
            Map<Channel, String> channelsX = ContainerMaps.getChannelsX();

            if (channelsX.containsKey(channel)) {
                String IMEIID = channelsX.get(channel);
                //存在保存起来
                if (redisCacheUtil.hasKey(IMEIID + "_PING")) {
                    //存在
                    String signal = redisCacheUtil.get(IMEIID + "_PING").toString();
                    redisCacheUtil.set(IMEIID + "_PING", signal, 180);
                }
                calculateUsingFactory(message,channel,msg[1] + msg[2]);
            } else {
                log.info("非法报文：" + message);
            }
        }
    }

    public static Optional<Operation> getOperation(String operator) {
        return Optional.ofNullable(operationMap.get(operator));
    }

    /**
     * 添加设备实例到MAP
     *
     * @param IMEIID
     * @param channel
     */
    public static void addInstance(String IMEIID,Channel channel) {
        ContainerMaps.addGatewayChannel(IMEIID, channel);
        ContainerMaps.addGatewayChannelX(channel, IMEIID);
        log.info("=================当前设备连接数: " + ContainerMaps.getChannelsSize());
    }


    /**
     * 往指定客户端发送指令
     *
     * @param cmd
     * @param channel
     * @throws Exception
     */
    public static void write(String cmd, Channel channel) throws Exception {
        byte[] respon = cmd.getBytes(CHARSET);
        //ByteBuf response = Unpooled.buffer(respon.length);
        PooledByteBufAllocator allocator = PooledByteBufAllocator.DEFAULT;
        ByteBuf response = allocator.buffer(respon.length);
        final ByteBuf data = channel.alloc().buffer(respon.length);
        data.writeBytes(respon);
        channel.writeAndFlush(data);
        channel.writeAndFlush(response);
    }

}
